package com.i2works.smartluolong.manage.controller.admin;


import com.i2works.smartluolong.manage.entity.admin.AdminUserDO;
import com.i2works.smartluolong.manage.entity.admin.AdminUserQuery;
import com.i2works.smartluolong.manage.service.admin.IAdminUserService;
import com.i2works.smartluolong.manage.utils.BaseModule;
import com.i2works.smartluolong.utils.base.MsgEnum;
import com.i2works.smartluolong.utils.base.URLConstant;
import com.i2works.smartluolong.utils.common.BaseUtils;
import com.i2works.smartluolong.utils.common.WebUtil;
import com.i2works.smartluolong.utils.exception.ServiceException;
import com.i2works.smartluolong.utils.shiro.SmartLuoLongToken;
import com.i2works.smartluolong.utils.web.HtmlConstant;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.util.SavedRequest;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import javax.servlet.http.HttpServletRequest;
import java.util.Date;

/**
 * 管理员账号基础
 *
 * @author koal <koal@vip.qq.com>
 * @date 2015年11月3日 下午8:35:20
 */
@Controller
@RequestMapping("/admin")
public class AdminController extends BaseModule {

    private final IAdminUserService adminUserService;

    @Autowired
    public AdminController(IAdminUserService adminUserService) {
        this.adminUserService = adminUserService;
    }


    /**
     * 登陆成功界面
     */
    @GetMapping(value = "/main")
    public String main() {
        return URLConstant.Admin.MAIN_URL;
    }

    /**
     * 登陆首页
     */

    @GetMapping("/login")
    public String login(HttpServletRequest request) {
        //获取用户
        Subject subject = SecurityUtils.getSubject();
        //判断是否授权和记住登录信息
        if (subject.isAuthenticated() || subject.isRemembered()) {
            return HtmlConstant.REDIRECT + WebUtil.domain(request) + URLConstant.Admin.MAIN_URL;
        }
        return URLConstant.Admin.LOGIN_URL;
    }


    /**
     * 登陆页面
     */
    @PostMapping(value = {"/login", "/index"})
    public String login(
            @RequestParam(value = "userName", required = false) String userName,
            @RequestParam(value = "password", required = false) String password,
            @RequestParam(value = "rememberMe", required = false) Boolean rememberMe,
            HttpServletRequest request, Model model) {
        String requestUrl = null;
        //判断账号密码是否为空
        if (StringUtils.isBlank(userName) || StringUtils.isBlank(password)) {
            model.addAttribute("errorMessage", MsgEnum.ACCESS_EMPTY.getMsg());
            return URLConstant.Admin.LOGIN_URL;
        }

        //获取用户
        Subject subject = SecurityUtils.getSubject();
        //判断是否授权和记住登录信息
        if (subject.isAuthenticated() || subject.isRemembered()) {
            return HtmlConstant.REDIRECT + WebUtil.domain(request) + URLConstant.Admin.MAIN_URL;
        }
        String errorMessage = null;
        UsernamePasswordToken token = new UsernamePasswordToken(userName, password, rememberMe);
        try {
            subject.login(token);
            // 获取登录前的页面
            SavedRequest savedRequest = WebUtils.getSavedRequest(request);
            if (savedRequest != null) {
                requestUrl = savedRequest.getRequestURI();
            }
        } catch (ExcessiveAttemptsException e) {
            //密码输错次数达到上限
            errorMessage = MsgEnum.ACCESS_LOCKED.getMsg();
            logger.info(MsgEnum.ACCESS_LOCKED.getMsg());
        } catch (UnknownAccountException e) {
            //为空
            errorMessage = MsgEnum.ACCESS_UNKNOW.getMsg();
            logger.info(MsgEnum.ACCESS_UNKNOW.getMsg());
        } catch (IncorrectCredentialsException e) {
            //错误
            errorMessage = MsgEnum.ACCESS_ERROR.getMsg();
            logger.info(MsgEnum.ACCESS_ERROR.getMsg());
        } catch (LockedAccountException e) {
            //账号已被停用
            errorMessage = MsgEnum.ACCESS_INVALID.getMsg();
            logger.info(MsgEnum.ACCESS_INVALID.getMsg());
        } catch (Exception e) {
            //登录失败
            errorMessage = MsgEnum.LOGIN_FAILED.getMsg();
            logger.info(MsgEnum.LOGIN_FAILED.getMsg());
        }
        return isLoginError(errorMessage, request, requestUrl, model);

    }


    /**
     * ukey登陆页面
     */
    @PostMapping("/ukeyLogin")
    public String ukeyLogin(@RequestParam(value = "ukey", required = false) String ukey, HttpServletRequest request, Model model) {
        String requestUrl = null;
        //判断ukey为空
        if (StringUtils.isBlank(ukey)) {
            model.addAttribute("errorMessage", MsgEnum.ACCESS_LOGIN_FAIL.getMsg());
            return URLConstant.Admin.LOGIN_URL;
        }
        String errorMessage = null;
        try {
            //查询用户
            AdminUserQuery accountQuery = new AdminUserQuery();
            accountQuery.setUkey(ukey);
            AdminUserDO adminUserDO = adminUserService.query(accountQuery);
            //获取用户
            Subject subject = SecurityUtils.getSubject();
            SmartLuoLongToken token = new SmartLuoLongToken(adminUserDO.getUserName());
            subject.login(token);
            // 获取登录前的页面
            SavedRequest savedRequest = WebUtils.getSavedRequest(request);
            if (savedRequest != null) {
                requestUrl = savedRequest.getRequestURI();
            }
        } catch (ExcessiveAttemptsException e) {
            //密码输错次数达到上限
            errorMessage = MsgEnum.ACCESS_LOCKED.getMsg();
            logger.info(MsgEnum.ACCESS_LOCKED.getMsg());
        } catch (UnknownAccountException e) {
            //为空
            errorMessage = MsgEnum.ACCESS_UNKNOW.getMsg();
            logger.info(MsgEnum.ACCESS_UNKNOW.getMsg());
        } catch (IncorrectCredentialsException e) {
            //错误
            errorMessage = MsgEnum.ACCESS_ERROR.getMsg();
            logger.info(MsgEnum.ACCESS_ERROR.getMsg());
        } catch (LockedAccountException e) {
            //账号已被停用
            errorMessage = MsgEnum.ACCESS_INVALID.getMsg();
            logger.info(MsgEnum.ACCESS_INVALID.getMsg());
        } catch (Exception e) {
            //登录失败
            errorMessage = MsgEnum.LOGIN_FAILED.getMsg();
            logger.info(MsgEnum.LOGIN_FAILED.getMsg());
        }
        return isLoginError(errorMessage, request, requestUrl, model);
    }


    /**
     * 退出登陆
     */
    @GetMapping("/logout")
    public String logout() {
        SecurityUtils.getSubject().logout();
        logger.info("退出登陆....................");
        return HtmlConstant.REDIRECT + URLConstant.Admin.LOGIN_URL;
    }


    /**
     * 跳转地址获取
     */
    @Deprecated
    private String redirectUrl(HttpServletRequest request) {
        //用于登录后跳转到之前网址
        String domain = WebUtil.domain(request);
        SavedRequest saveRequest = WebUtils.getSavedRequest(request);
        if (saveRequest != null && StringUtils.isNotBlank(saveRequest.getRequestUrl())) {
            return HtmlConstant.REDIRECT + saveRequest.getRequestUrl();
        } else {
            return HtmlConstant.REDIRECT + WebUtil.domain(request) + URLConstant.Admin.MAIN_URL;
        }
    }


    /**
     * 登录错误
     */
    private String isLoginError(String errorMessage, HttpServletRequest request, String requestUrl, Model model) {
        if (StringUtils.isNotBlank(errorMessage)) {
            model.addAttribute("errorMessage", errorMessage);
            //return HtmlConstant.REDIRECT + WebUtil.domain(request) + URLConstant.Admin.LOGIN_URL;
            return URLConstant.Admin.LOGIN_URL;
        } else {
            // 设置登陆IP和登陆时间
            try {
                AdminUserDO userDO = getLoginUser();
                userDO.setLoginIp(BaseUtils.getIP(request));
                userDO.setLoginTime(new Date());
                adminUserService.updateStatus(userDO);
            } catch (ServiceException e) {
                logger.error("登录后设置用户信息失败：" + e.getMessage());
            }
            //用于跳转到之前网址
            return HtmlConstant.REDIRECT + WebUtil.domain(request) + URLConstant.Admin.MAIN_URL;

        }
    }
}
